package com.lagou.edu.boss.rest.authroity;

import com.lagou.edu.authority.MenuRemoteService;
import com.lagou.edu.authority.RoleRemoteService;
import com.lagou.edu.authority.dto.AllocateRoleMenuDTO;
import com.lagou.edu.authority.dto.MenuDTO;
import com.lagou.edu.authority.dto.MenuNodeDTO;
import com.lagou.edu.boss.entity.form.AllocateRoleMenuForm;
import com.lagou.edu.boss.entity.form.MenuForm;
import com.lagou.edu.common.entity.vo.Result;
import com.lagou.edu.common.util.ConvertUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author lm
 * @since 2021/11/4 15:54
 */
@Slf4j
@RestController
@RequestMapping("/menu")
public class MenuController {
    @Autowired
    MenuRemoteService menuRemoteService;

    @Autowired
    RoleRemoteService roleRemoteService;

    @ApiOperation(value = "保存或新增菜单", notes = "保存或新增菜单")
    @PostMapping(value = "/saveOrUpdate")
    public Result<Boolean> saveOrUpdate(@RequestBody MenuForm menuForm) {
        MenuDTO menuDTO = ConvertUtils.convert(menuForm, MenuDTO.class);
        if (Objects.isNull(menuDTO.getId())) {
            //menuDTO.setCreatedBy(UserManager.getUserName());
            menuDTO.setCreatedBy("张三");
            menuDTO.setCreatedTime(new Date());
        }
        //menuDTO.setUpdatedBy(UserManager.getUserName());
        menuDTO.setUpdatedBy("张三");
        return Result.success(menuRemoteService.saveOrUpdate(menuDTO));
    }

    @ApiOperation(value = "获取所有菜单", notes = "获取所有菜单")
    @GetMapping("/getAll")
    public Result getAllMenu() {
        return Result.success(menuRemoteService.getAllMenu());
    }

    @GetMapping("/getEditMenuInfo")
    public Result<Map> getEditMenuInfo(@RequestParam("id") Integer id) {
        Map<String, Object> resultMap = new HashMap<>();
        List<MenuNodeDTO> menuNodeDTOList = menuRemoteService.getMenuNodeList();
        MenuDTO menuDTO = menuRemoteService.getMenuById(id);

        if (Objects.nonNull(menuDTO)) {
            Integer parentId = menuDTO.getParentId();
            // 设置当前正在编辑的菜单
            menuNodeDTOList.forEach(menuNodeDTO -> setSelectedFlag(parentId, menuNodeDTO));
        }

        resultMap.put("menuInfo", menuDTO);
        resultMap.put("parentMenuList", menuNodeDTOList);
        return Result.success(resultMap);
    }

    /**
     * 选中当前菜单的上级菜单，置为选中状态
     *
     * @param parentId    当前菜单的父级菜单ID
     * @param menuNodeDTO 所有菜单列表
     */
    private void setSelectedFlag(Integer parentId, MenuNodeDTO menuNodeDTO) {
        if (Objects.equals(menuNodeDTO.getId(), parentId)) {
            menuNodeDTO.setSelected(true);
            return;
        }
        if (CollectionUtils.isEmpty(menuNodeDTO.getSubMenuList())) {
            return;
        }
        menuNodeDTO.getSubMenuList().forEach(subMenuNode -> setSelectedFlag(parentId, subMenuNode));
    }

    /**
     * 获取菜单树
     *
     * @return
     */
    @GetMapping("/getMenuNodeList")
    public Result getMenuNodeList() {
        return Result.success(menuRemoteService.getMenuNodeList());
    }

    @ApiOperation(value = "获取角色拥有的菜单列表", notes = "在给角色分配菜单时，跳转到角色-菜单列表页，并标记哪些菜单已分配给该角色")
    @GetMapping("/getRoleMenus")
    public Result<List<MenuNodeDTO>> getRoleMenus(@RequestParam Integer roleId) {
        List<MenuDTO> roleMenuList = menuRemoteService.getMenuByRoleId(roleId);
        List<MenuNodeDTO> menuNodeList = menuRemoteService.getMenuNodeList();
        if (CollectionUtils.isEmpty(menuNodeList)) {
            return Result.fail("未查询到菜单列表");
        }
        final Set<Integer> roleMenuIds = roleMenuList.stream().map(role -> role.getId()).collect(Collectors.toSet());
        menuNodeList.stream().forEach(menuNodeDTO -> setSelectedFlag(menuNodeDTO, roleMenuIds));
        return Result.success(menuNodeList);
    }

    private void setSelectedFlag(MenuNodeDTO menuNodeDTO, Set<Integer> roleMenuIds) {
        if (roleMenuIds.contains(menuNodeDTO.getId())) {
            menuNodeDTO.setSelected(true);
        }
        if (CollectionUtils.isEmpty(menuNodeDTO.getSubMenuList())) {
            return;
        }
        menuNodeDTO.getSubMenuList().stream().forEach(subMenuNode -> setSelectedFlag(subMenuNode, roleMenuIds));
    }

    @ApiOperation(value = "给角色分配菜单")
    @PostMapping("/allocateRoleMenus")
    public Result<Boolean> allocateRoleMenus(@RequestBody AllocateRoleMenuForm allocateRoleMenuForm) {
        log.info("Allocate role menus, params:{}", allocateRoleMenuForm);
        if (Objects.isNull(allocateRoleMenuForm.getRoleId())) {
            return Result.fail("角色ID不能为空");
        }
        AllocateRoleMenuDTO allocateRoleMenuDTO = ConvertUtils.convert(allocateRoleMenuForm, AllocateRoleMenuDTO.class);
//        allocateRoleMenuDTO.setCreatedBy(UserManager.getUserName());
//        allocateRoleMenuDTO.setUpdatedBy(UserManager.getUserName());
        allocateRoleMenuDTO.setCreatedBy("張三");
        allocateRoleMenuDTO.setUpdatedBy("張三");
        return Result.success(menuRemoteService.allocateRoleMenus(allocateRoleMenuDTO));
    }
}
